CLASS LCL_TREE_EVENT_RECEIVER DEFINITION PUBLIC FINAL.

    PUBLIC SECTION.
    METHODS handle_item_double_click
    FOR EVENT ITEM_DOUBLE_CLICK OF CL_GUI_ALV_TREE
    IMPORTING
        FIELDNAME NODE_KEY.
        
    METHODS ON_FUNCTION_SELECTED
    FOR EVENT FUNCTION_SELECTED OF CL_GUI_TOOLBAR
    IMPORTING FCODE.
ENDCLASS.

CLASS LCL_TREE_EVENT_RECEIVER IMPLEMENTATION.
METHOD handle_item_double_click.
CALL METHOD REF_GRID_TREE->GET_EXPANDED_NODES
CHANGING
    CT_EXPANDED_NODES = LT_SELECTED_NODES.
    G_CUR_NODE_H[] = LT_SELECTED_NODES[].

CALL METHOD REF_GRID_TREE->GET_SELECTED_NODES
CHANGING
CT_SELECTED_NODES = LT_SELECTED_NODES.

CLEAR WA_OUT.
CALL METHOD REF_GRID_TREE->GET_OUTTAB_LINE(
    EXPORTING
    I_NODE_KEY = NODE_KEY
    IMPORTING
        E_OUTTAB_LINE = WA_OUT
        E_NODE_TEXT = L_NODE_KEY
        ET_ITEM_LAYOUT = LT_ITEM_LAYOUT
        ES_NODE_LAYOUT = ES_NODE_LAYOUT).

IF SY-SUBRC = 0.
    IF WA_OUT IS NOT INITIAL.
        IF WA_OUT-CK = ''.
            WA_OUT-CK = 'X'.
        ELSE.
            WA_OUT-CK = ''.
        ENDIF.
        LOOP AT GT_OUT ASSIGNING <FS> WHERE POSID = WA_OUT-POSID.
        <FS>-CK = WA_OUT-CK.
        ENDLOOP.
        T_OUT[] = GT_OUT[].
    ENDIF.

    PERFORM INIT_TREE.
    CALL METHOD REF_GRID_TREE->FRONTEND_UPDATE.
    CALL METHOD REF_GRID_TREE->UPDATE_CALCULATIONS.

ENDIF.
ENDMETHOD.

METHOD ON_FUNCTION_SELECTED.
CASE FCODE.
    WHEN 'ALL'.
        LOOP AT GT_OUT ASSIGNING <FS>.
        <FS>-CK = 'X'.
        ENDLOOP.
        T_OUT[] = GT_OUT[].

        PERFORM INIT_TREE.
        CALL METHOD REF_GRID_TREE->FRONTEND_UPDATE.
        CALL METHOD REF_GRID_TREE->UPDATE_CALCULATIONS.
    WHEN 'SAL'.
        LOOP AT GT_OUT ASSIGNING <FS>.
            <FS>-CK = ''.
        ENDLOOP.

        PERFORM INIT_TREE.
        CALL METHOD REF_GRID_TREE->FRONTEND_UPDATE.
        CALL METHOD REF_GRID_TREE->UPDATE_CALCULATIONS.
ENDCASE.
ENDMETHOD.
ENDCLASS.

MODULE STATUS_9000 OUTPUT.
SET PF-STATUS 'MAIN100'.
IF REF_GRID_TREE IS INITIAL.
    PERFORM INIT_TREE.
    CALL METHOD CL_GUI_CFW=>FLUSH
    EXCEPTIONS
    CNTL_SYSTEM_ERROR = 1
    CNTL_ERROR = 2.
ENDIF.
ENDMODULE.

FORM INIT_TREE.
DATA L_CUR_NODE TYPE LVC_NKEY.
DATA L_CUR_NODE_H TYPE LVC_NKEY.
IF GT_FCAT_TREE IS INITIAL.
    PERFORM FRM_ADD_FIELD USING:
    GT_FCAT_TREE 'MC' '名称' '' '' '' 25,
    GT_FCAT_TREE 'LX' '节点类型' '' '' '' 25,
    GT_FCAT_TREE 'CK' '预算控制' '' '' '' 25,
ENDIF.

IF REF_GRID_TREE IS NOT INITIAL.
    CALL METHOD REF_GRID_TREE->FREE.
    REFRESH GT_OUT.
ENDIF.

IF REF_GRID_TREE IS INITIAL.
    CREATE OBJECT REF_CONTAINER_PARENT
    EXPORTING
    CONTAINER_NAME = 'PARENT'
    EXCEPTIONS
    CNTL_ERROR = 1
    CNTL_SYSTEM_ERROR = 2
    CREATE_ERROR = 3
    LIFETIME_ERROR = 4
    LIFETIME_DYNPRO_DYNPRO_LINK = 5.
ENDIF.

CREATE OBJECT REF_GRID_TREE
EXPORTING
PARENT = REF_CONTAINER_PARENT
NODE_SELECTION_MODE = CL_GUI_COLUMN_TREE=>NODE_SEL_MODE_SINGLE
ITEM_SELECTION = 'X'
NO_HTML_HEADER = 'X'
NO_TOOLBAR = ''
EXCEPTIONS
CNTL_ERROR = 1
CNTL_SYSTEM_ERROR = 2
CREATE_ERROR = 3
LIFETIME_ERROR = 4
ILLEGAL_NODE_SELECTION_MODE = 5
FAILED = 6
ILLEGAL_COLUMN_NAME = 7.

IF SY-SUBRC = 0.
    MESSAGE X208(00) WITH 'ERROR'.
ENDIF.

DATA L_HIERARCHY_HEADER TYPE TREEV_HHDR.

PERFORM BUILD_HIERARCHY_HEADER CHANGING L_HIERARCHY_HEADER.

LS_VARI-REPORT = SY-REPID.

CALL METHOD REF_GRID_TREE->SET_TABLE_FOR_FIRST_DISPLAY
EXPORTING
IS_HIERARCHY_HEADER = L_HIERARCHY_HEADER
CHANGING
IT_OUTTAB = GT_OUT[]
IT_FIELDCATALOG = GT_FCAT_TREE.

IF T_OUT[] IS INITIAL.
    PERFORM get_data.
ELSE.
    GT_OUT[] = T_OUT[].
ENDIF.

DATA LT_OUT LIKE TABLE OF GT_OUT WITH HEADER LINE.
DATA WA_OUT LIKE GT_OUT.

LT_OUT[] = GT_OUT[].
REFRESH GT_OUT.
LOOP AT LT_OUT ASSIGNING <FS2>.
IF <FS2>-POSID_1 = ''.
    PERFORM ADD_NODES USING <FS2>
    ''
    CHANGING L_CUR_NODE.
    L_CUR_NODE_H = L_CUR_NODE.
    APPEND L_CUR_NODE_H TO G_CUR_NODE_H.
ELSE.
    READ TABLE LT_OUT ASSIGNING <FS> WITH KEY POSID = <FS2>-POSID_1.
    PERFORM ADD_NODES USING <FS2>
    <FS>-NODEID
    CHANGING L_CUR_NODE.
ENDIF.
<FS2>-NODEID = L_CUR_NODE.
ENDLOOP.

SORT G_CUR_NODE_H.
DELETE ADJACENT DUPLICATES FROM G_CUR_NODE_H COMPARING ALL FIELDS.
IF G_CUR_NODE_H[] IS NOT INITIAL.
    CALL METHOD REF_GRID_TREE->CT_EXPANDED_NODES
    EXPORTING
    IT_NODE_KEY = G_CUR_NODE_H[].

ENDIF.
PERFORM CHANGE_TOOLBAR.
PERFORM SET_EVENT_HANDLER.
CALL METHOD REF_GRID_TREE->UPDATE_CALCULATIONS.
CALL METHOD REF_GRID_TREE->FRONTEND_UPDATE.

ENDFORM.

FORM CHANGE_TOOLBAR.
    CALL METHOD REF_GRID_TREE->GET_TOOLBAR_OBJECT
    IMPORTING
    ER_TOOLBAR = MR_TOOLBAR.

    CHECK NOT MR_TOOLBAR IS INITIAL.

    CALL METHOD MR_TOOLBAR->ADD_BUTTON
    EXPORTING
    FCODE = ''
    ICON = ''
    BUTN_TYPE = CNTB_BTYPE_SEP
    TEXT = ''
    QUICKINFO = 'THIS IS SEPERATOR'.

    CALL METHOD MR_TOOLBAR->ADD_BUTTON
    EXPORTING
    FCODE = 'ALL'
    ICON = '@4D@'
    BUTN_TYPE = CNTB_BTYPE_BUTTON
    TEXT = ''
    QUICKINFO = '选中全部'.

    CALL METHOD MR_TOOLBAR->ADD_BUTTON
    EXPORTING
    FCODE = 'SAL'
    ICON = '@4D@'
    BUTN_TYPE = CNTB_BTYPE_BUTTON
    TEXT = ''
    QUICKINFO = '反选全部'.

ENDFORM.

FORM SET_EVENT_HANDLER.
DATA: LT_EVENTS TYPE CNTL_SIMPLE_EVENTS,
    L_EVENT TYPE CNTL_SIMPLE_EVENT,
    L_EVENT_RECEIVER TYPE REF TO LCL_TREE_EVENT_RECEIVER.

 CALL METHOD REF_GRID_TREE->GET_REGISTERED_EVENTS
 IMPORTING
 EVENTS = LT_EVENTS.
 
ENDFORM.